﻿using System;
using System.Collections.Generic;
using ConsoleCommand.Commands;
using ConsoleCommand.Utilities;

namespace ConsoleCommand
{
    class CommandFactory
    {
        static Dictionary<string,CommandType> controlCharacterMap=new Dictionary<string,CommandType>{
            {"?",CommandType.Help}
        };

        static public ICommand Create(IDictionary<CommandParameter,string> parameters){
            Guard.True(parameters.ContainsKey(CommandParameter.Command), "The required parameter \"Command\" is missing.");
            Guard.True(!String.IsNullOrEmpty(parameters[CommandParameter.Command]), "The required parameter \"Command\" is missing.");
            CommandType type = GetCommandType(parameters[CommandParameter.Command]);
            ICommand command=GetCommand(type,parameters);
            return command;
        }

        static CommandType GetCommandType(string type) {
            try{
                CommandType command;
                if(controlCharacterMap.ContainsKey(type)){
                    command=controlCharacterMap[type];
                }else{
                    command=(CommandType)Enum.Parse(typeof(CommandType),type,true);
                }
                return command;
            }catch(ArgumentException){}
            throw new ArgumentOutOfRangeException("type",type,"Invalid Command.");
        }

        static ICommand GetCommand(CommandType type,IDictionary<CommandParameter,string> parameters){
            ICommand command;
            switch (type){
                case CommandType.BC:
                case CommandType.BackColor:
                    Guard.True(parameters.ContainsKey(CommandParameter.Color), "The required parameter \"Color\" is missing.");
                    command=new BackColorCommand(parameters[CommandParameter.Color]);
                    break;
                case CommandType.C:
                case CommandType.Color:
                    Guard.True(parameters.ContainsKey(CommandParameter.Color), "The required parameter \"Color\" is missing.");
                    command=new ColorCommand(parameters[CommandParameter.Color]);
                    break;
                case CommandType.E:
                case CommandType.Extract:
                case CommandType.ExtractResource:
                    Guard.True(parameters.ContainsKey(CommandParameter.Assembly), "The required parameter \"Assembly\" is missing.");
                    string resource=parameters.ContainsKey(CommandParameter.Resource)?parameters[CommandParameter.Resource]:null;
                    command=new ExtractResourceCommand(parameters[CommandParameter.Assembly], resource);
                    break;
                case CommandType.L:
                case CommandType.List:
                case CommandType.ListResources:
                    Guard.True(parameters.ContainsKey(CommandParameter.Assembly), "The required parameter \"Assembly\" is missing.");
                    command=new ListResourcesCommand(parameters[CommandParameter.Assembly]);
                    break;
                default:
                    throw new NotImplementedException(String.Format("The command \"{0}\" has not been implemented.", type));
            }
            return command;
        }

    }
}
